package com.powerbosframework.context;

import java.util.List;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.jdom.Document;
import org.jdom.Element;
import com.powerbosframework.beans.BeanException;
import com.powerbosframework.beans.BeanObjectFactory;
import com.powerbosframework.beans.entity.BeanEntity;
import com.powerbosframework.beans.entity.ViewEntity;
import com.powerbosframework.context.ApplicatioinContextException;
import com.powerbosframework.context.ApplicationContext;
import com.powerbosframework.context.resource.Resource;
import com.powerbosframework.context.resource.ResourceImpl;
import com.powerbosframework.log.LogFactory;
import com.powerbosframework.log.Logger;
import com.powerbosframework.util.StringUtil;
import com.powerbosframework.util.NumberUtil;
import com.powerbosframework.util.XMLUtil;
import com.powerbosframework.web.action.GlobalMessage;
import com.powerbosframework.web.form.MultipartForm;
import com.powerbosframework.web.util.RequestURI;

/**
 * 应用上下文管理
 * 
 * @author youfu.wang
 * @version 1.0
 */
public class XmlApplicationContext implements ApplicationContext {
	private String configuration;
	private static Logger log = LogFactory.getInstance();
	private BeanObjectFactory beanObjectFactory = new BeanObjectFactory();
	private XMLUtil xmlUtil = new XMLUtil();
	//上下文常量属性
	private static final String CONSTANTS_ENCODING="context.encoding";
	private static final String CONSTANTS_MULTIPART_SAVEDIR="multipart.savedir";
	private static final String CONSTANTS_MULTIPART_MAXSIZE="multipart.maxsize";
	private static final String CONSTANTS_MULTIPART_EXTENSIONS="multipart.extensions";
	//数据源缓存属性常量
	public static final String CACHE_PROVIDER_CLASS = "cacheProviderClass";

	static Class class$(String s) {
		Class cls = null;
		try {
			cls = Thread.currentThread().getContextClassLoader().loadClass(s);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		if (cls == null) {
			try {
				cls = Class.forName(s);
			} catch (ClassNotFoundException classnotfoundexception) {
				throw new NoClassDefFoundError(classnotfoundexception
						.getMessage());
			}
		}
		return cls;
	}

	public XmlApplicationContext() {
		configuration = "context-cfg.xml";
	}

	public XmlApplicationContext(String configuration) {
		this.configuration = configuration;
	}

	/**
	 * 销毁应用上下文内存
	 */
	@Override
	public void free() {
		beanObjectFactory.clear();
	}

	/**
	 * 加载应用上下文资源
	 * 
	 * @throws ApplicatioinContextException
	 * @throws IOException
	 */
	public void load() throws IOException, ApplicatioinContextException {
		this.load(configuration);
	}

	/**
	 * 加载应用上下文资源
	 * 
	 * @param location
	 * @throws IOException
	 * @throws ApplicatioinContextException
	 * @throws BeanException
	 */
	public void load(String location) throws IOException,
			ApplicatioinContextException {		
		this.loadContextConstants(location);
		beanObjectFactory.loadBeanObject(location);
	}
	private void loadContextConstants(String location) throws IOException, ApplicatioinContextException{
		Resource resource = new ResourceImpl(location);
		InputStream stream = resource.getInputStream();
		if (stream == null)
			throw new IOException(resource + "资源文件没有找到");
		Document doc = xmlUtil.parse(stream);
		if (doc == null)
			throw new ApplicatioinContextException(resource + "资源文件解析失败");
		Element rootE = doc.getRootElement();
		if (rootE == null)
			throw new ApplicatioinContextException(resource + "资源文件解析失败");
		List constants = rootE.getChildren("constant");
		if (constants == null)
			return;
		for(int i=0;i<constants.size();i++){
			Element constantE=(Element)constants.get(i);
			if(this.CONSTANTS_ENCODING.equals(StringUtil.replaceNull(constantE.getAttributeValue("name")))){
				RequestURI.CONTEXT_ENCODING=StringUtil.replaceNull(constantE.getAttributeValue("value"));
			}else if(this.CONSTANTS_MULTIPART_SAVEDIR.equals(StringUtil.replaceNull(constantE.getAttributeValue("name")))){
				String saveDir=StringUtil.replaceNull(constantE.getAttributeValue("value"));
				if(!"".equals(saveDir)){
					if(saveDir.startsWith("/")||saveDir.startsWith(File.separator)){							
						saveDir=saveDir.substring(1, saveDir.length());
						MultipartForm.saveDir=GlobalMessage.GLOBAL_PATH+File.separator+saveDir;
					}else{
						MultipartForm.saveDir=GlobalMessage.GLOBAL_PATH+File.separator+StringUtil.replaceNull(constantE.getAttributeValue("value"));
					}					
				}				
				//log.info("******MultipartForm.saveDir: "+MultipartForm.saveDir);
			}else if(this.CONSTANTS_MULTIPART_MAXSIZE.equals(StringUtil.replaceNull(constantE.getAttributeValue("name")))){
				if(!"".equals(StringUtil.replaceNull(constantE.getAttributeValue("value")))&&NumberUtil.isNumeric(StringUtil.replaceNull(constantE.getAttributeValue("value")))){
					int maxSize=Integer.parseInt(StringUtil.replaceNull(constantE.getAttributeValue("value")));
					MultipartForm.maxSize=maxSize;
				}		
				//log.info("******MultipartForm.maxSize: "+MultipartForm.maxSize);
			}else if(this.CONSTANTS_MULTIPART_EXTENSIONS.equals(StringUtil.replaceNull(constantE.getAttributeValue("name")))){
				if(!"".equals(StringUtil.replaceNull(constantE.getAttributeValue("value")))){
					MultipartForm.extensions=StringUtil.replaceNull(constantE.getAttributeValue("value"));
				}
				//log.info("******MultipartForm.extensions: "+MultipartForm.extensions);
			}
		}
	}	

	public Object getBeanObject(String id) {
		return beanObjectFactory.getBean(id);
	}
	public ViewEntity getGlobalView(String name){
		return beanObjectFactory.getGlobalView(name);		
	}
	public BeanEntity getBeanEntity(String id){
		return beanObjectFactory.getBeanEntity(id);
	}
	public static void main(String[] args){
		try {
			new XmlApplicationContext().load();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ApplicatioinContextException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
